import { modifyProfile } from "@/api/modules/model/profile";
import { modifySchema, replaceSchema } from "@/api/modules/model/schema";
import { setSensor } from "@/api/modules/model/sensor";
import DialogBox from "@/components/DialogBox";
import { JsonSchemaEmitParam } from "@/components/JsonSchemaForm/interface/jsonschema";
import JsonSchemaEditor from "@/components/JsonSchemaForm/JsonSchemaForm.vue";
import VideoPanel from "@/components/VideoPanel";
import { DataPreview } from "@/enums/dataPreview";
import { ResultEnum } from "@/enums/httpEnum";
import { AuthBtns, SchemaNodeKey, SchemaNodeType } from "@/utils/constants";
import mittBus from "@/utils/mittBus";
import { showTips } from "@/utils/util";
import ConfigDetail from "@/views/iot/alarm/components/configDetail";
import jsonpath from "jsonpath";
import { defineComponent } from "vue";
import { useRoute, useRouter } from "vue-router";
import { openWin } from "../../../../utils/routerUtil";
import {
	parseDeviceSchemaFromSensor,
	parseProfileFromDeviceSensorParam,
	parseProfileFromRealtimeSensorValue,
	parseSchemaFromDevice,
	parseSchemaFromGatewaySensor
} from "../../../../utils/schema";
import DataChart from "../components/DataChart";
import HistoryFile from "../components/HistoryFile";
import ImgCard from "../components/ImgCard";
import Location from "../components/Location";
/**
 * 设备参数信息,scheme中的config下面子设备参数信息（排除sensor节点）
 * 相关参数：设备接入端口、地址、采集周期、上报周期
 */
export default defineComponent({
	emits: [],
	setup() {
		const route = useRoute();
		const router = useRouter();

		//设备参数配置模型
		const schema = inject<any>(SchemaNodeKey.schema);
		const gatewaySchema = inject<any>(SchemaNodeKey.gatewaySchema);
		const profile = inject<any>(SchemaNodeKey.profile);
		const disabledMod = inject<any>(AuthBtns.disabledMod);

		//变量模型profile：单位、名称、描述等
		let sensorRealtimeValue = ref<any>({});
		let sensorProfile = ref<any>({});
		const refreshDeviceDetail = () => {
			mittBus.emit("refreshDeviceDetail");
		};
		const saveSchema = (loading: boolean) => {
			if (disabledMod.value) return;
			replaceSchema({
				idSn: route.query.sn || route.query.id,
				nodePath: "properties.sensor",
				data: {
					type: "object",
					title: schema.value?.properties?.sensor?.title || "传感量",
					properties: schemaTree.root.properties
				}
			}).then(res => {
				let ok = res.code == ResultEnum.SUCCESS;
				if (loading) {
					showTips(res.code, "设备配置");
				}
				if (ok) {
					refreshDeviceDetail();
				}
			});
		};

		// if (!Object.keys(sensorRealtimeValue).length && import.meta.env.DEV) {
		// 	sensorRealtimeValue = {import { img } from '@/assets/images/500.png';

		// 		...sensorRealtimeValue,
		// 		k3: 33,
		// 		video: "http://xxx.xxx.flv",
		// 		latlng: { lat: 31.313048, lng: 121.299517 },
		// 		web: "http://baidu.com"
		// 	};
		// }

		//缓存sensor数据
		const schemaTree = reactive({
			root: {
				type: "object",
				title: schema.value?.properties?.config?.properties?.sensor?.title || "设备模型",
				properties: {},
				required: []
			}
		});
		const currentPath = ref();
		const currentSchema = ref();
		onBeforeMount(() => {
			initSensor();
			//监听树历史数据图标点击
			mittBus.on("clickValueIcon", data => {
				let param = data as JsonSchemaEmitParam;
				currentPath.value = param.dataPath;
				currentSchema.value = param.schemaInfo;
				switch (param.dataType) {
					case DataPreview.historyChart.type:
						dataChartDialog.visible = true;
						dataChartDialog.dataValue = param.dataValue;
						dataChartDialog.dataKey = param.dataPath;
						break;
					case DataPreview.video.type:
						videoDialog.videoUrl = param.dataValue;
						videoDialog.visible = true;
						break;
					case DataPreview.img.type:
						imgDialog.dataKey = param.dataPath;
						imgDialog.visible = true;
						break;
					case DataPreview.file.type:
						fileDialog.dataKey = param.dataPath;
						fileDialog.visible = true;
						break;
					case DataPreview.location.type:
						locationDialog.dataKey = param.dataPath;
						locationDialog.detail.location = param.dataValue;
						locationDialog.visible = true;
						break;
					case DataPreview.configAlarm.type:
						configAlarmDialog.visible = true;
						break;
					case DataPreview.web.type:
						openWin(param.dataValue, router);
						break;
				}
			});
			//监听变量配置返回数据处理
			mittBus.on("clickSensorParam", (path: any) => {
				sensorFormDialog.path = path;
				const sensorTemplate = parseSchemaFromDevice(schema.value)?.sensor?.properties || {};
				if (jsonpath.query(sensorTemplate, `$.${path.replaceAll(".", ".properties.")}`).length) {
					sensorFormDialog.schema.root = {
						...jsonpath.query(sensorTemplate, `$.${path.replaceAll(".", ".properties.")}`)[0],
						title: path,
						type: SchemaNodeType.object
					};
				} else {
					//网关和设备的变量配置都为空的时候插入空root
					sensorFormDialog.schema.root =
						JSON.stringify(parseSchemaFromGatewaySensor(gatewaySchema.value)) == "{}"
							? { title: path, type: SchemaNodeType.object, properties: {}, required: [] }
							: parseSchemaFromGatewaySensor(gatewaySchema.value);
				}
				sensorFormDialog.detail = jsonpath.query(sensorProfile.value, `$.${path}`).length
					? jsonpath.query(sensorProfile.value, `$.${path}`)[0]
					: {};
				sensorFormDialog.currentDetail = JSON.stringify(sensorFormDialog.detail);
				sensorFormDialog.currentSchema = JSON.stringify(sensorFormDialog.schema);
				sensorFormDialog.visible = true;
			});
		});

		watch(
			() => schema.value,
			() => {
				initSensor();
			}
		);
		//初始化上报数据，没有模型就自动增加
		const initSensor = async () => {
			//变量模型profile：单位、名称、描述等
			sensorRealtimeValue.value = parseProfileFromRealtimeSensorValue(profile.value);
			sensorProfile.value = parseProfileFromDeviceSensorParam(profile.value);
			const sensorSchema = parseDeviceSchemaFromSensor(schema.value);
			schemaTree.root.properties = sensorSchema;
			const applySchema = (value: any, path: string) => {
				//当前有相同Schema的key不执行
				if (!jsonpath.query(sensorSchema, `$.${path}`).length) {
					if (typeof value == "object") {
						jsonpath.value(sensorSchema, `$.${path}`, { type: "object" });
						for (let ck in value) {
							let cPath = path ? path + ".properties." + ck + "" : ck;
							jsonpath.value(sensorSchema, `$.${cPath}`);
							applySchema(value[ck], cPath);
						}
					} else {
						jsonpath.value(sensorSchema, `$.${path}`, { type: typeof value });
					}
				}
			};
			for (let key in sensorRealtimeValue.value) {
				applySchema(sensorRealtimeValue.value[key], key);
			}
		};
		const getDialogTitle = (title: string): string => {
			if (route.query.sn) {
				return `${route.query.sn} - ${title}`;
			} else {
				return title;
			}
		};
		//历史数据
		const dataChartDialog = reactive<any>({
			title: getDialogTitle(`历史数据趋势`),
			dataValue: null,
			dataKey: "",
			visible: false
		});
		//历史图片
		const imgDialog = reactive<any>({
			title: getDialogTitle(`历史图片`),
			dataKey: "",
			visible: false
		});
		//文件
		const fileDialog = reactive<any>({
			title: getDialogTitle(`文件列表`),
			detail: {},
			dataKey: "",
			visible: false
		});
		const locationDialog = reactive({
			visible: false,
			dataKey: "",
			detail: {
				location: { lat: null, lng: null, address: null }
			},
			title: getDialogTitle("位置与轨迹")
		});
		const configAlarmDialog = reactive({
			visible: false,
			title: getDialogTitle("告警配置")
		});
		const videoDialog = reactive({
			videoUrl: "",
			visible: false,
			title: getDialogTitle("实时视频")
		});
		//变量配置弹窗
		const sensorFormDialog = reactive({
			visible: false,
			schema: { root: {} },
			detail: {},
			title: "添加变量",
			path: "",
			currentSchema: "",
			currentDetail: ""
		});
		const setProfileDialog = reactive({ visible: false });
		const saveProfile = async () => {
			setSensor({ idSn: route.query.sn || route.query.id, data: sensorRealtimeValue.value }).then(res => {
				let ok = showTips(res.code, "参数配置");
				if (ok) {
					setProfileDialog.visible = false;
					refreshDeviceDetail();
				}
			});
		};
		//添加变量配置
		const addSensor = async () => {
			sensorFormDialog.visible = false;
			if (sensorFormDialog.currentSchema != JSON.stringify(sensorFormDialog.schema)) {
				let data = {};
				jsonpath.value(data, `$..${sensorFormDialog.path.replaceAll(".", ".properties.")}`, sensorFormDialog.schema.root);
				let resSchema = await modifySchema({
					idSn: route.query.sn,
					nodePath: "properties.config.properties.sensor.properties",
					data
				});
				if (sensorFormDialog.currentDetail != JSON.stringify(sensorFormDialog.detail)) {
					let ok = showTips(resSchema.code, "变量配置");
					if (ok) {
						sensorFormDialog.currentSchema = JSON.stringify(sensorFormDialog.schema);
						refreshDeviceDetail();
					}
				}
			}
			if (sensorFormDialog.currentDetail != JSON.stringify(sensorFormDialog.detail)) {
				let data = {};
				jsonpath.value(data, `$..${sensorFormDialog.path}`, sensorFormDialog.detail);
				let resProfile = await modifyProfile({
					idSn: route.query.sn,
					nodePath: "config.sensor",
					data
				});
				let ok = showTips(resProfile.code, "变量配置");
				if (ok) {
					sensorFormDialog.currentDetail = JSON.stringify(sensorFormDialog.detail);
					sensorFormDialog.currentSchema = JSON.stringify(sensorFormDialog.schema);
					refreshDeviceDetail();
				}
			}
		};
		return () => {
			return (
				<div class="block-basic p-8">
					{/*变量数据趋势*/}
					<DialogBox
						class="dialog-dense"
						hideFooter
						v-model:visible={dataChartDialog.visible}
						width="75vw"
						title={dataChartDialog.title}
					>
						<DataChart
							dataKey={dataChartDialog.dataKey}
							dataValue={dataChartDialog.dataValue}
							class="bg-gray-100"
							height="55vh"
						/>
					</DialogBox>
					<DialogBox class="dialog-dense" hideFooter v-model:visible={imgDialog.visible} width="75vw" title={imgDialog.title}>
						{imgDialog.visible ? <ImgCard dataKey={imgDialog.dataKey} class="bg-gray-100" height="75vh" /> : null}
					</DialogBox>
					<DialogBox
						class="dialog-dense"
						footerLabel={["关闭"]}
						v-model:visible={fileDialog.visible}
						width="75vw"
						title={fileDialog.title}
					>
						{fileDialog.visible ? (
							<HistoryFile
								dataKey={fileDialog.dataKey}
								class="bg-gray-100"
								style="height:75vh"
								onFileInfo={(val: string) => (fileDialog.detail.fileInfo = val)}
							/>
						) : null}
						{/* 文件信息 */}
						{fileDialog.detail.fileInfo ? <div class="ext-file-info">{fileDialog.detail.fileInfo}</div> : null}
					</DialogBox>
					{/*视频窗口*/}
					<DialogBox
						title={videoDialog.title}
						v-model:visible={videoDialog.visible}
						hideFooter
						class="dialog-dense video-dialog"
						width="65vw"
					>
						{videoDialog.visible ? <VideoPanel videoUrl={videoDialog.videoUrl} /> : null}
					</DialogBox>
					{/*位置信息*/}
					<DialogBox
						title={locationDialog.title}
						v-model:visible={locationDialog.visible}
						footerLabel={["关闭"]}
						class="dialog-dense"
						width="85vw"
					>
						{locationDialog.visible ? (
							<Location
								dataKey={locationDialog.dataKey}
								devSn={route.query.sn as string}
								dataInfo={locationDialog.detail}
								style="height:75vh"
								onAddress={(val: any) => (locationDialog.detail.location!.address = val.address)}
							/>
						) : null}
						<div class="address-detail">
							<div>{locationDialog.detail.location?.address}</div>
							<div class="pl-1">
								（{locationDialog.detail.location.lng},{locationDialog.detail.location.lat}）
							</div>
						</div>
					</DialogBox>
					{/*告警设置*/}
					<DialogBox
						title={configAlarmDialog.title}
						v-model:visible={configAlarmDialog.visible}
						footerLabel={["关闭"]}
						width="65vw"
					>
						{configAlarmDialog.visible ? <ConfigDetail sensorKey={currentPath.value} title={currentSchema.value.title} /> : null}
					</DialogBox>
					<DialogBox
						title="变量配置"
						v-model:visible={sensorFormDialog.visible}
						footerLabel={["关闭", "保存"]}
						width="980px"
						onConfirm={() => addSensor()}
					>
						<JsonSchemaEditor
							class="w-full"
							value={sensorFormDialog.schema}
							lang="zh_CN"
							ext-type
							jsonValue={sensorFormDialog.detail}
							disabled={disabledMod.value}
						/>
					</DialogBox>
					<DialogBox
						title="数据下发"
						v-model:visible={setProfileDialog.visible}
						footerLabel={["关闭", "保存"]}
						width="980px"
						onConfirm={() => saveProfile()}
					>
						<JsonSchemaEditor class="w-full" value={schemaTree} lang="zh_CN" jsonValue={sensorRealtimeValue.value} />
					</DialogBox>
					<div class="flex mb-4 justify-between">
						<div class="flex">
							<el-button type="primary" plain onClick={() => saveSchema(true)} disabled={disabledMod.value}>
								保存模型
							</el-button>
							<el-button
								type="primary"
								plain
								onClick={() => {
									setProfileDialog.visible = true;
								}}
								disabled={disabledMod.value}
							>
								数据下发
							</el-button>
						</div>
						{/* <el-button class="ml-auto" link type="primary" onClick={() => (dialogVisible.value = true)}>
							预览JSON
						</el-button> */}
					</div>
					<JsonSchemaEditor
						isSensor
						class="w-full"
						value={schemaTree}
						lang="zh_CN"
						custom
						jsonParam={sensorProfile.value}
						jsonValue={sensorRealtimeValue.value}
						disabled={disabledMod.value}
					/>
				</div>
			);
		};
	}
});
